package br.com.unioConci.upload.negocio;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.Transaction;

import br.com.r2.exception.R2Exception;
import br.com.r2.util.hibernate.business.NegocioThrow;
import br.com.r2.util.hibernate.business.R2HbNgc;
import br.com.r2.util.tipodado.Data;
import br.com.r2.util.tipodado.DataHora;
import br.com.r2.util.tipodado.Flag;
import br.com.r2.util.tipodado.Inteiro;
import br.com.r2.util.tipodado.InteiroLongo;
import br.com.r2.util.tipodado.Moeda;
import br.com.r2.util.tipodado.Texto;
import br.com.r2.util.tipodado.YesNo;
import br.com.unioConci.cadastro.vo.LocalPagamentoVo;
import br.com.unioConci.seguranca.vo.UsuarioVo;
import br.com.unioConci.upload.vo.ArquivoFinanceiroAnaliticoVo;
import br.com.unioConci.upload.vo.ArquivoFinanceiroRazaoSinteticoVo;
import br.com.unioConci.upload.vo.ArquivoRazaoAnaliticoVo;
import br.com.unioConci.upload.vo.UploadArquivoVo;
import br.com.unioConci.util.hibernate.business.HibernateUtil;

public class UploadArquivoFinanceiroRazaoNgc extends R2HbNgc<UploadArquivoVo>
{

   private Map filtroPropriedade = new HashMap();

   private Map restritores = new HashMap();

   public static final String TIPO_ARQUIVO_FINANCEIRO_SINTETICO = "1";

   public static final String TIPO_ARQUIVO_RAZAO_SINTETICO = "2";

   public static final int TIPO_CONCILIACAO_ANALITICO = 1;

   public static final int TIPO_CONCILIACAO_SINTETICO = 2;
   
   private static UploadArquivoFinanceiroRazaoNgc instancia = null;
   
   private UploadArquivoFinanceiroRazaoNgc()
   {
      init(restritores, filtroPropriedade, UploadArquivoVo.class);
   }

   public static UploadArquivoFinanceiroRazaoNgc getInstancia()
   {
      if (instancia == null)
      {
         instancia = new UploadArquivoFinanceiroRazaoNgc();
      }
      return instancia;
   }
   
   @Override
   protected Criteria montaCriteria(Session session, int join)
   {
      Criteria criteria = session.createCriteria(UploadArquivoVo.class);
      return criteria;
   }
   
   public void receberArquivoSintetico(UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      Session sessao = HibernateUtil.getSession();
      sessao.setFlushMode(FlushMode.COMMIT);
      Transaction tx = sessao.beginTransaction();
      try
      {
         this.receberArquivoSintetico(sessao, uploadArquivoVo);
         
         tx.commit();
      }
      catch (Exception e)
      {
         throw NegocioThrow.getInstancia().catchHBEdicaoSession(e, tx);
      }
      finally
      {
         sessao.close();
      }
   }
   
   public void receberArquivoSintetico(Session sessao, UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      BufferedReader in = null;
      String linha = null;
      try
      {
         validarReceber(uploadArquivoVo);
         HashMap parametros = uploadArquivoVo.getParametros();
         parametros.put("usuario", uploadArquivoVo.getUsuarioVo().getCodigo());
         
         in = new BufferedReader(new FileReader(uploadArquivoVo.getArquivo()));
         String[] campos = null;
         while (in.ready())
         {
            linha = in.readLine();
            if (linha != null && !linha.trim().equals(""))
            {
               campos = linha.split(";");
               gravarDetalheSintetico(sessao, campos, parametros);
               sessao.flush();
            }
         }
      }
      catch (FileNotFoundException fileNotFoundException)
      {
         throw new R2Exception("upload_erro_arquivo_nao_encontrado");
      }
      catch (IOException e)
      {
         throw new R2Exception("upload_erro_arquivo_leitura");
      }
      catch (Exception e)
      {
         throw new R2Exception("upload_erro_arquivo_leitura_dados");
      }
   }
   
   private void gravarDetalheSintetico(Session sessao, String[] listaCampos, HashMap parametros) throws R2Exception
   {
      ArquivoFinanceiroRazaoSinteticoVo arquivoVo = new ArquivoFinanceiroRazaoSinteticoVo();
      String campo = null;
      
      // 1. DATA DA BAIXA
      campo = listaCampos[0]; 
      campo = campo.trim();
      Calendar calendar = new GregorianCalendar();
      String ano = campo.substring(6, campo.length()); 
      String mes = campo.substring(3, 5);
      String dia = campo.substring(0, 2);
      calendar.set(Integer.parseInt(ano), Integer.parseInt(mes)-1, Integer.parseInt(dia));
      arquivoVo.setDataBaixa(new Data(calendar.getTime()));
      
      // 2. LOCAL DE PAGAMENTO
      campo = listaCampos[1];
      campo = campo.trim();
      LocalPagamentoVo localPagamentoVo = new LocalPagamentoVo();
      localPagamentoVo.setCodigo(new Texto(campo));
      arquivoVo.setLocalPagamentoVo(localPagamentoVo);
      
      // 3. VALOR DO PAGAMENTO
      campo = listaCampos[2];
      arquivoVo.setValorPagamento(new Moeda(campo.trim()));
      
      // 4. TIPO DO ARQUIVO
      campo = (String) parametros.get("tipoArquivo");
      arquivoVo.setTipoArquivo(new Inteiro(campo.trim()));

      // 5. SITUACAO
      arquivoVo.setSituacao(new Flag(YesNo.YES));
      
      // 6. USUARIO DE INCLUSAO
      InteiroLongo usuario = (InteiroLongo) parametros.get("usuario");
      UsuarioVo usuarioVo = new UsuarioVo();
      usuarioVo.setCodigo(usuario);
      arquivoVo.setUsuarioInclusaoVo(usuarioVo);
      
      // 7. DATA DE INCLUSAO
      arquivoVo.setDataInclusao(new DataHora(new Date().getTime()));
      
      // 8. GRAVANDO NO BANCO
      ArquivoFinanceiroRazaoSinteticoNgc.getInstancia().inserir(sessao, arquivoVo);
      
   }

   private void validarReceber(UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      if (uploadArquivoVo == null)
      {
         throw new R2Exception("campo.obrigatorio", new String[]{"lbl_arquivo"});
      }
      
      if (uploadArquivoVo.getArquivo() == null)
      {
         throw new R2Exception("campo.obrigatorio", new String[]{"lbl_arquivo"});
      }
      
      if (uploadArquivoVo.getUsuarioVo() == null)
      {
         throw new R2Exception("campo.obrigatorio", new String[]{"lbl_usuario_recebimento"});
      }
   }

   public void receberArquivoRazaoAnalitico(UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      Session sessao = HibernateUtil.getSession();
      sessao.setFlushMode(FlushMode.COMMIT);
      Transaction tx = sessao.beginTransaction();
      try
      {
         receberArquivoRazaoAnalitico(sessao, uploadArquivoVo);
         tx.commit();
      }
      catch (Exception e)
      {
         throw NegocioThrow.getInstancia().catchHBEdicaoSession(e, tx);
      }
      finally
      {
         sessao.close();
      }
   }

   public void receberArquivoRazaoAnalitico(Session sessao, UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      BufferedReader in = null;
      String linha = null;
      try
      {
         validarReceber(uploadArquivoVo);
         HashMap parametros = uploadArquivoVo.getParametros();
         if (parametros == null)
         {
            parametros = new HashMap();
         }
         parametros.put("usuario", uploadArquivoVo.getUsuarioVo().getCodigo());
         
         in = new BufferedReader(new FileReader(uploadArquivoVo.getArquivo()));
         String[] campos = null;
         while (in.ready())
         {
            linha = in.readLine();
            if (linha != null && !linha.trim().equals(""))
            {
               campos = linha.split(";");
               gravarDetalheRazaoAnalitico(sessao, campos, parametros);
               sessao.flush();
            }
         }
      }
      catch (FileNotFoundException fileNotFoundException)
      {
         throw new R2Exception("upload_erro_arquivo_nao_encontrado");
      }
      catch (IOException e)
      {
         throw new R2Exception("upload_erro_arquivo_leitura");
      }
      catch (Exception e)
      {
         throw new R2Exception("upload_erro_arquivo_leitura_dados");
      }
   }

   private void gravarDetalheRazaoAnalitico(Session sessao, String[] listaCampos, HashMap parametros) throws R2Exception
   {
      ArquivoRazaoAnaliticoVo arquivoVo = new ArquivoRazaoAnaliticoVo();
      String campo = null;
      
      // 1. DATA DA BAIXA
      campo = listaCampos[0]; 
      campo = campo.trim();
      Calendar calendar = new GregorianCalendar();
      String ano = campo.substring(6, campo.length()); 
      String mes = campo.substring(3, 5);
      String dia = campo.substring(0, 2);
      calendar.set(Integer.parseInt(ano), Integer.parseInt(mes)-1, Integer.parseInt(dia));
      arquivoVo.setDataBaixa(new Data(calendar.getTime()));

      // 2. HISTORICO
      campo = listaCampos[1];
      arquivoVo.setHistorico(new Texto(campo.trim()));

      // 3. VALOR DO PAGAMENTO
      campo = listaCampos[2];
      arquivoVo.setValorPagamento(new Moeda(campo.trim()));
      
      // 4. SITUACAO
      arquivoVo.setSituacao(new Flag(YesNo.YES));
      
      // 5. USUARIO DE INCLUSAO
      InteiroLongo usuario = (InteiroLongo) parametros.get("usuario");
      UsuarioVo usuarioVo = new UsuarioVo();
      usuarioVo.setCodigo(usuario);
      arquivoVo.setUsuarioInclusaoVo(usuarioVo);
      
      // 6. DATA DE INCLUSAO
      arquivoVo.setDataInclusao(new DataHora(new Date().getTime()));
      
      // 7. GRAVANDO NO BANCO
      ArquivoRazaoAnaliticoNgc.getInstancia().inserir(sessao, arquivoVo);
   }

   public void receberArquivoFinanceiroAnalitico(UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      Session sessao = HibernateUtil.getSession();
      sessao.setFlushMode(FlushMode.COMMIT);
      Transaction tx = sessao.beginTransaction();
      try
      {
         receberArquivoFinanceiroAnalitico(sessao, uploadArquivoVo);
         tx.commit();
      }
      catch (Exception e)
      {
         throw NegocioThrow.getInstancia().catchHBEdicaoSession(e, tx);
      }
      finally
      {
         sessao.close();
      }
   }
   
   public void receberArquivoFinanceiroAnalitico(Session sessao, UploadArquivoVo uploadArquivoVo) throws R2Exception
   {
      BufferedReader in = null;
      String linha = null;
      try
      {
         validarReceber(uploadArquivoVo);
         HashMap parametros = uploadArquivoVo.getParametros();
         if (parametros == null)
         {
            parametros = new HashMap();
         }
         parametros.put("usuario", uploadArquivoVo.getUsuarioVo().getCodigo());
         
         in = new BufferedReader(new FileReader(uploadArquivoVo.getArquivo()));
         String[] campos = null;
         while (in.ready())
         {
            linha = in.readLine();
            if (linha != null && !linha.trim().equals(""))
            {
               campos = linha.split(";");
               gravarDetalheFinanceiroAnalitico(sessao, campos, parametros);
               sessao.flush();
            }
         }
      }
      catch (FileNotFoundException fileNotFoundException)
      {
         throw new R2Exception("upload_erro_arquivo_nao_encontrado");
      }
      catch (IOException e)
      {
         throw new R2Exception("upload_erro_arquivo_leitura");
      }
      catch (Exception e)
      {
         throw new R2Exception("upload_erro_arquivo_leitura_dados");
      }
   }

   private void gravarDetalheFinanceiroAnalitico(Session sessao, String[] listaCampos, HashMap parametros) throws R2Exception
   {
      ArquivoFinanceiroAnaliticoVo arquivoVo = new ArquivoFinanceiroAnaliticoVo();
      String campo = null;
      
      // 1. DATA DA BAIXA
      campo = listaCampos[0]; 
      campo = campo.trim();
      Calendar calendar = new GregorianCalendar();
      String ano = campo.substring(6, campo.length()); 
      String mes = campo.substring(3, 5);
      String dia = campo.substring(0, 2);
      calendar.set(Integer.parseInt(ano), Integer.parseInt(mes)-1, Integer.parseInt(dia));
      arquivoVo.setDataBaixa(new Data(calendar.getTime()));

      // 2. LOCAL DO PAGAMENTO
      campo = listaCampos[1];
      campo = campo.trim();
      LocalPagamentoVo localPagamentoVo = new LocalPagamentoVo();
      localPagamentoVo.setCodigo(new Texto(campo));
      arquivoVo.setLocalPagamentoVo(localPagamentoVo);

      // 3. VALOR DO PAGAMENTO
      campo = listaCampos[2];
      arquivoVo.setValorPagamento(new Moeda(campo.trim()));

      // 4. CLIENTE
      campo = listaCampos[3];
      arquivoVo.setCodigoCliente(new InteiroLongo(campo.trim()));

      // 5. NOME DO CLIENTE
      campo = listaCampos[4];
      arquivoVo.setNomeCliente(new Texto(campo.trim()));

      // 6. FATURA
      campo = listaCampos[5];
      arquivoVo.setFatura(new Texto(campo.trim()));

      // 7. CONTRATO
      campo = listaCampos[6];
      arquivoVo.setCodigoContrato(new InteiroLongo(campo.trim()));
      
      // 8. SITUACAO
      arquivoVo.setSituacao(new Flag(YesNo.YES));
      
      // 9. FLAG DE CONCILIACAO
      arquivoVo.setFlagConciliado(new Flag(YesNo.NO));
      
      // 10. USUARIO DE INCLUSAO
      InteiroLongo usuario = (InteiroLongo) parametros.get("usuario");
      UsuarioVo usuarioVo = new UsuarioVo();
      usuarioVo.setCodigo(usuario);
      arquivoVo.setUsuarioInclusaoVo(usuarioVo);
      
      // 11. DATA DE INCLUSAO
      arquivoVo.setDataInclusao(new DataHora(new Date().getTime()));
      
      // 12. GRAVANDO NO BANCO
      ArquivoFinanceiroAnaliticoNgc.getInstancia().inserir(sessao, arquivoVo);
   }


   @Override
   protected Map filtroPropriedade()
   {
      return filtroPropriedade;
   }

   @Override
   protected Map restritores()
   {
      return restritores;
   }

}
